package cn.edu.pku.ss.situationperceiver;

import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import cn.edu.pku.ss.situationperceiver.AllJoynService.ControlDiscoveryProgressInstruction;
import cn.edu.pku.ss.situationperceiver.AllJoynService.PeerConnectedState;

public class MainActivity extends Activity {
	/**
	 * Main Activity is defined here. Most UI interacts and modules' status is
	 * showed to the smart phone screen through the listeners and method
	 * interfaces in this class.
	 * 
	 */

	private static final String TAG = "sp.MainActivity";

	IntentFilter alljoynIntentFilter;

	ConnectStatusBroadcastReceiver csReceiver; // Broadcast Receiver to receive
												// connect status from AllJoyn
												// Service
	TextView connectStatus_TextView; // TextView for Connect Status
	TextView groupStatus_TextView; // TextView for group status
	TextView peerslist_TextView; // TextView for peers in the group
	
	Button sendRequest_Button;//Button to send request message for test

	private ProgressDialog discoveringDialog; // Progress Dialog for discovering\
	
	private Messenger mMessenger;

	private ServiceConnection alljoynConn = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			Toast.makeText(getBaseContext(), "AllJoyn Service Disconnected",
					Toast.LENGTH_SHORT).show();

		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			
			mMessenger = new Messenger(service);
			Toast.makeText(getBaseContext(), "AllJoyn Service Connected",
					Toast.LENGTH_SHORT).show();

		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.i(TAG, "onCreate()");
		setContentView(R.layout.activity_main);

		connectStatus_TextView = (TextView) findViewById(R.id.connectStatusTextView);
		groupStatus_TextView = (TextView) findViewById(R.id.groupStatusTextView);
		peerslist_TextView = (TextView) findViewById(R.id.peersTextView);
		
		sendRequest_Button=(Button)findViewById(R.id.sendRequestMessageButton);
		sendRequest_Button.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				//Call the mContextShareInterface.ReceiveContextSharingRequest() in AllJoynService
				Message msg = Message.obtain(null, AllJoynService.REQUEST_SEND_MESSAGE);
				try {
					mMessenger.send(msg);
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		});

		// Start and bind the alljoyn service
		Intent alljoynIntent = new Intent(MainActivity.this,
				AllJoynService.class);
		bindService(alljoynIntent, alljoynConn, Context.BIND_AUTO_CREATE);

		csReceiver = new ConnectStatusBroadcastReceiver();
		alljoynIntentFilter = new IntentFilter();
		String csActionName = (String) getString(R.string.updateConnectStatusIntentAction); // add
																							// update
																							// connect
																							// status
																							// listener
																							// to
																							// intent
																							// filter
		String cpActionName = (String) getString(R.string.controlDiscoveryProgressAction); // add
																							// control
																							// progress
																							// listener
																							// to
																							// intent
																							// filter
		String ugsActionName = (String) getString(R.string.updateGroupStatusAction); // add
																						// update
																						// group
																						// name
																						// listener
																						// to
																						// intent
																						// filter
		String psActionName = (String) getString(R.string.updatePeersListAction); // add
																					// peers
																					// status
																					// listener
																					// to
																					// intent
																					// filter
		
		String rmActionName = (String) getString(R.string.showRequestMessageAction);
		
		alljoynIntentFilter.addAction(csActionName);
		alljoynIntentFilter.addAction(cpActionName);
		alljoynIntentFilter.addAction(ugsActionName);
		alljoynIntentFilter.addAction(psActionName);
		alljoynIntentFilter.addAction(rmActionName);
		registerReceiver(csReceiver, alljoynIntentFilter);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		Intent csIntent = new Intent();
		csIntent.setClass(this, AllJoynService.class);
		stopService(csIntent);

		this.unbindService(alljoynConn);
		Log.i(TAG, "onDestroy()");
		unregisterReceiver(csReceiver);
	}

	
	public class ConnectStatusBroadcastReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String intentActionName = intent.getAction();
			String csActionName = (String) getString(R.string.updateConnectStatusIntentAction);
			String cpActionName = (String) getString(R.string.controlDiscoveryProgressAction);
			String updateGroupStatusActionName = (String) getString(R.string.updateGroupStatusAction);
			String psActionName = (String) getString(R.string.updatePeersListAction);
			String rmActionName = (String) getString(R.string.showRequestMessageAction);
			
			if (intentActionName.startsWith(csActionName)) {
				/*
				 * Receive and react to Connect Status Broadcast
				 */
				String csName = (String) getString(R.string.ConnectStatusName);
				String connectStatus;
				PeerConnectedState status = (PeerConnectedState) intent
						.getSerializableExtra(csName);
				switch (status) {
				case DISCONNECTED:
					connectStatus = "DISCONNECTED";
					break;
				case SESSION_HOLDER:
					connectStatus = "SESSION_HOLDER";
					break;
				case CONNECTED:
					connectStatus = "CONNECTED";
					break;
				case DISCOVERING:
					connectStatus = "DISCOVERING";
					break;
				case SESSION_LOST:
					connectStatus = "SESSION_LOST";
					break;
				case JOINED:
					connectStatus = "JOINED";
					break;
				default:
					connectStatus = "DEFAULT CONNECT STATUS";
					Log.i(TAG,
							"MainActivity.ConnectStatusBroadcastReceiver.onReceive->default.");
					break;
				}
				connectStatus_TextView.setText(csName + ": " + connectStatus);
			} else if (intentActionName.startsWith(cpActionName)) {
				/*
				 * Receive and react to Checking Process Broadcast (Progress Dialog)
				 */
				String instructionName = (String) getString(R.string.DiscoveryProgressInstruction);
				ControlDiscoveryProgressInstruction instruction = (ControlDiscoveryProgressInstruction) intent
						.getSerializableExtra(instructionName);
				switch (instruction) {
				case START_PROGRESS_DIALOG: {
					discoveringDialog = ProgressDialog.show(MainActivity.this,
							"", "Scan existing session...\nPlease wait...",
							true, true);
					break;
				}
				case STOP_PROGRESS_DIALOG: {
					if (discoveringDialog != null
							&& discoveringDialog.isShowing()) {
						discoveringDialog.dismiss();
					}
					break;
				}
				}
			} else if (intentActionName.startsWith(updateGroupStatusActionName)) {
				/*
				 * Receive and react to Group Status Broadcast (Show the connected group name)
				 */
				String groupStatusName = (String) getString(R.string.GroupStatusName);
				String groupStatus = intent.getStringExtra(groupStatusName);
				groupStatus_TextView.setText(groupStatus);
			} else if (intentActionName.startsWith(psActionName)) {
				/*
				 * Receive and react to Peers List Broadcast
				 */
				String extraPeersListName = (String) getString(R.string.peersIntentExtraPeersListName);
				ArrayList<String> peersList = (ArrayList<String>) intent
						.getSerializableExtra(extraPeersListName);
				if (peersList.size() != 0) {
					String peerStatus = "Reachable Peers: " + peersList.size()
							+ " ";
					int count = 1;
					for (String peername : peersList) {
						peerStatus += "(" + count++ + ")" + " " + peername;
					}
					peerslist_TextView.setText(peerStatus);
				} else {
					peerslist_TextView.setText("No peer is reachable.");
				}

			}else if(intentActionName.startsWith(rmActionName)){
				String extraPeersListName = (String) getString(R.string.requestMessageName);
				String time = intent.getStringExtra(extraPeersListName);
				
				Toast.makeText(getBaseContext(), "Get a request message time: "+time,
						Toast.LENGTH_LONG).show();

			} 
			else {
				Log.i(TAG,
						"got an intent from alljoyn service but can't identify the method process with it.");
			}

		}
	}
}
